﻿using DX;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Tools.Plugins.MockServer
{
    interface IUserManagement
    {
        bool AssessRigth(string name, string database);
        UserProfile GetUser(string name);
    }
    class UserManagement: IUserManagement
    {
        public UserManagement(IServiceProvider serviceProvider, ISerializeProvider serializeProvider)
        {
            if (File.Exists("users.json"))
            {
                var json = File.ReadAllText("users.json");
                dbsetUser = serializeProvider.Deserialize<List<UserProfile>>(json);
            }

        }

        IList<UserProfile> dbsetUser = new List<UserProfile>();
        public UserProfile GetUser(string name)
        {
            return dbsetUser.FirstOrDefault(x => x.Name == name);
        }

        public bool AssessRigth(string name, string database)
        {
            return dbsetUser.Any(x => x.Name == name && x.Database == database);
        }
    }
    class UserProfile
    {
        public string Name { get; set; }
        public string Password { get; set; }
        public string Database { get; set; }
    }
    class ClientSession : IDisposable
    {
        private TcpClient client;
        private NetworkStream stream;
        private bool disposedValue;

        public ClientSession(TcpClient client)
        {
            this.client = client;
            stream = client.GetStream();
        }

        public byte[] AuthResponse { get; set; }
        public string Database { get; set; }
        public string Username { get; set; }

        public PasswordPlugin PasswordPlugin { get; set; }
        public byte[] AuthPluginData { get; set; }
        public byte Sequence { get; internal set; }

    

        internal Stream GetStream()
        {
            return stream; 
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                stream.Dispose();
                client.Dispose();
                disposedValue = true;
            }
        }

     
        public void Dispose()
        {
         
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }
    class PasswordValidator
    {
        internal static byte[] CalculateScramble(byte[] password, byte[] salt, HashAlgorithm hashAlgorithm)
        {
            if (password.Length == 0) return new byte[1];
            SHA1 sha = SHA1.Create();
            byte[] firstHash = sha.ComputeHash(password);
            byte[] secondHash = sha.ComputeHash(firstHash);
            byte[] input = new byte[salt.Length + secondHash.Length];
            Array.Copy(salt, 0, input, 0, salt.Length);
            Array.Copy(secondHash, 0, input, salt.Length, secondHash.Length);
            byte[] thirdHash = sha.ComputeHash(input);
            for (int i = 1; i < thirdHash.Length; i++)
            {
                thirdHash[i] = (byte)(thirdHash[i] ^ firstHash[i - 1]);
            }
            return thirdHash;
        }
        static bool Validate(HashAlgorithm algorithm, byte[] clientResponse, string password, byte[] salt)
        {
            byte[] expected = CalculateScramble(Encoding.UTF8.GetBytes(password), salt, algorithm);


            bool flag = clientResponse.SequenceEqual(expected);
            return flag;
        }
        public static bool ValidateSHA256(byte[] clientResponse, string password, byte[] salt)
        {
            var algorithm = SHA256.Create();

            return Validate(algorithm, clientResponse, password, salt);
        }
        public static bool ValidateSHA1(byte[] clientResponse, string password, byte[] salt)
        {
            if (salt.Length != 20)
            {
                throw new ArgumentException("Invalid salt length, expected 20 bytes");
            }
            var algorithm = SHA1.Create();
            return Validate(algorithm, clientResponse, password, salt);
        }
    }

    static class PacketWriterExtensions
    {
        public static void WriteColumnDefinition(this PacketWriter writer, string columnName, string columnType)
        {
            writer.WriteLengthEncodedString("def"); // Catalog
            writer.WriteLengthEncodedString("");    // Schema
            writer.WriteLengthEncodedString("");    // Table别名
            writer.WriteLengthEncodedString("");    // 原始表名
            writer.WriteLengthEncodedString(columnName); // 列名
            writer.WriteLengthEncodedString(columnName); // 原始列名
            writer.WriteByte(0x0c);                 // 填充符
            writer.WriteUInt16(0x21);               // 字符集: utf8_general_ci
            writer.WriteUInt32(256);                // 列长度
            writer.WriteByte(0x0f);                 // 类型: VARCHAR
            writer.WriteUInt16(0x0000);             // Flags
            writer.WriteByte(0x00);                // Decimals
        }
        /*
        public static void SetServerInfo(this PacketWriter writer, ushort connectioID, ushort saltPart1, ushort lowerFlags)
        {
            writer.WriteByte(0x0A);                     // 协议版本
            writer.WriteNullTerminated("5.6.0");    // 服务器版本
            writer.WriteUInt32(connectioID);                      // 连接 ID
            writer.WriteBytes(saltPart1);               // 盐第一部分（8字节）
            writer.WriteByte(0x00);                     // 保留填充
            writer.WriteUInt16(lowerFlags);             // 能力标志低位
            writer.WriteByte(0x21);                     // 字符集（UTF8）
            writer.WriteUInt16(ServerStatus.Autocommit);                 // 状态标志
            writer.WriteUInt16(upperFlags);             // 能力标志高位
            writer.WriteByte(0x14);                     // 盐总长度（20字节）
            writer.WriteBytes(new byte[10]);            // 保留字段
            writer.WriteBytes(saltPart2Modified);               // 盐第二部分（12字节）
            writer.WriteNullTerminated(passwordPlugin); // 认证插件名
        }*/
    }
    class PacketWriter : IDisposable
    {
        public PacketWriter()
        {
            _stream = new MemoryStream();
        }
        private MemoryStream _stream;
        private bool disposedValue;

        public PacketWriter WriteByte(byte value)
        {
            _stream.WriteByte(value);
            return this;
        }
        public PacketWriter WriteUInt16(ushort value)
        {
            _stream.WriteByte((byte)(value & 0xFF));
            _stream.WriteByte((byte)((value >> 8) & 0xFF));
            return this;
        }
        public PacketWriter WriteUInt32(uint value)
        {
            _stream.WriteByte((byte)(value & 0xFF));
            _stream.WriteByte((byte)((value >> 8) & 0xFF));
            _stream.WriteByte((byte)((value >> 16) & 0xFF));
            _stream.WriteByte((byte)((value >> 24) & 0xFF));
            return this;
        }
        public PacketWriter WriteUInt64(ulong value)
        {
            for (int i = 0; i < 8; i++)
            {
                _stream.WriteByte((byte)(value & 0xFF));
                value >>= 8;
            }
            return this;
        }
        public PacketWriter WriteBytes(byte[] data)
        {
            _stream.Write(data, 0, data.Length);
            return this;
        }
        public PacketWriter WriteNullTerminated(string value)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(value);
            _stream.Write(bytes, 0, bytes.Length);
            _stream.WriteByte(0x00); // 自动添加Null终止符
            return this;
        }
        public PacketWriter WriteLengthEncodedInteger(ulong value)
        {
            if (value < 251)
            {
                _stream.WriteByte((byte)value);
                return this;
            }
            if (value < 65536)
            {
                _stream.WriteByte(0xFC);
                WriteUInt16((ushort)value);
                return this;
            }
            if (value < 16777216)
            {
                _stream.WriteByte(0xFD);
                _stream.WriteByte((byte)(value & 0xFF));
                _stream.WriteByte((byte)((value >> 8) & 0xFF));
                _stream.WriteByte((byte)((value >> 16) & 0xFF));
                return this;
            }
            _stream.WriteByte(0xFE);
            WriteUInt64(value);
            return this;
        }
        public PacketWriter WriteLengthEncodedString(string value)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(value);
            WriteLengthEncodedInteger((ulong)bytes.Length);
            _stream.Write(bytes, 0, bytes.Length);
            return this;
        }

        public byte[] ToPacket(byte sequence)
        {
            byte[] payload = _stream.ToArray();
            int payloadLength = payload.Length;
            if (payloadLength > 0xFFFFFF)
            {
                throw new InvalidOperationException("Packet too large");
            }
            byte[] packet = new byte[payload.Length + 4];
            packet[0] = (byte)(payload.Length & 0xFF);
            packet[1] = (byte)((payload.Length >> 8) & 0xFF);
            packet[2] = (byte)((payload.Length >> 16) & 0xFF);
            packet[3] = sequence;
            Array.Copy(payload, 0, packet, 4, payload.Length);
            return packet;
        }
        public byte[] ToArray() => _stream.ToArray();

        protected virtual void Dispose(bool disposing)
        {
            if (disposedValue) return;
            disposedValue = true;
            if (!disposing) return;
            if (_stream == null) return;
            _stream.Dispose();
            _stream = null;






        }



        void IDisposable.Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }
    class ServerStatus
    {
        public const ushort InTrans = 0x0001;
        public const ushort Autocommit = 0x0002;
        public const ushort MoreResultsExists = 0x0008;
        public const ushort QueryNoGoodIndexUsed = 0x0010;
        public const ushort QueryNoIndexUsed = 0x0020;
    }
    class ClientCapabilities
    {
        // 基础能力标志 (低16位)
        public const ushort CLIENT_LONG_PASSWORD = 0x00000001;   // 使用安全密码认证
        public const ushort CLIENT_FOUND_ROWS = 0x00000002;      // 返回匹配行数而非受影响行数
        public const ushort CLIENT_LONG_FLAG = 0x00000004;       // 支持所有列标志
        public const ushort CLIENT_CONNECT_WITH_DB = 0x00000008; // 指定数据库连接
        public const ushort CLIENT_NO_SCHEMA = 0x00000010;       // 禁止 db.table.column 语法
        public const ushort CLIENT_COMPRESS = 0x00000020;        // 支持压缩协议
        public const ushort CLIENT_ODBC = 0x00000040;            // ODBC客户端
        public const ushort CLIENT_LOCAL_FILES = 0x00000080;     // 支持LOAD DATA LOCAL
        public const ushort CLIENT_IGNORE_SPACE = 0x00000100;    // 忽略函数名后空格
        public const ushort CLIENT_PROTOCOL_41 = 0x00000200;     // 4.1协议支持  
        public const ushort CLIENT_INTERACTIVE = 0x00000400;     // 交互式客户端
        public const ushort CLIENT_SSL = 0x00000800;             // SSL加密支持
        public const ushort CLIENT_IGNORE_SIGPIPE = 0x00001000;  // 忽略SIGPIPE错误
        public const ushort CLIENT_TRANSACTIONS = 0x00002000;    // 事务支持
        public const ushort CLIENT_RESERVED = 0x00004000;        // 保留标志
        public const ushort CLIENT_SECURE_CONNECTION = 0x00008000;// 安全连接  
        public const ushort CLIENT_PLUGIN_AUTH = 0x0008;      // 插件认证 



        // 扩展能力标志 (高16位)
        public const uint CLIENT_MULTI_STATEMENTS = 0x00010000; // 多语句支持
        public const uint CLIENT_MULTI_RESULTS = 0x00020000;    // 多结果集支持
        public const uint CLIENT_PS_MULTI_RESULTS = 0x00040000; // 存储过程多结果集
        public const uint CLIENT_CONNECT_ATTRS = 0x00100000;    // 连接属性
        public const uint CLIENT_PLUGIN_AUTH_LENENC = 0x00200000;// 长度编码数据
        public const uint CLIENT_CLIENT_SSL_VERIFY_SERVER_CERT = 0x00400000;
        public const uint CLIENT_CLIENT_SESSION_TRACK = 0x00800000;
        public const uint CLIENT_DEPRECATE_EOF = 0x01000000;     // 使用OK包代替EOF
        public static ushort GetLowerFlags()
        {
            return CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION;
        }


        public static ushort GetUpperFlags()
        {

            return CLIENT_PLUGIN_AUTH;
        }
        public static bool HasAuth(uint value)
        {
            return (value & CLIENT_SECURE_CONNECTION) == CLIENT_SECURE_CONNECTION;
        }
        public static bool WithDB(uint value)
        {
            return (value & CLIENT_CONNECT_WITH_DB) == CLIENT_CONNECT_WITH_DB;
        }
    }
    public class MysqlOption
    {
        public int Port { get; set; }

        public string Version { get; set; } = "8.3";

        public string AppName { get; set; } = "mockmysql";
        public PasswordPlugin PasswordPlugin { get; set; } = PasswordPlugin.mysql_native_password;
    }
    public enum PasswordPlugin
    {
        mysql_native_password,
        caching_sha2_password
    }
    public static class MysqlExtensions
    {
        public static void UseMysql(this IServiceCollection services, Action<MysqlOption> config)
        {
            services.AddHttpClient("a1", opt => { 
            
            });
            services.PostConfigure<MysqlOption>(config);
            services.AddSingleton<ClientSessionManagment>();
            services.AddSingleton<MySqlServer>();
            services.AddScoped<ProcessorFacotry>();
            services.AddScoped<AuthProcessor>();
            services.AddScoped<QueryProcessor>();
            services.AddScoped<HandshakeProcessor>();
            services.AddScoped<ClientSession>(n =>
            {
                var fatory = n.GetRequiredService<ProcessorFacotry>();
                return fatory.Session;
            });
            services.AddScoped<IUserManagement,UserManagement>();

        }
        public static async Task MySqlStart(Action<MysqlOption> config)
        {
            ServiceCollection services = new ServiceCollection();

#if DEBUG
            services.AddLogging(logging =>
            {
                logging.SetMinimumLevel(LogLevel.Debug);
                logging.AddConsole();
            });
#else

            services.AddLogging();
#endif
            services.UseMysql(config);
            var serviceProvider = services.BuildServiceProvider();
            var sqlserver = serviceProvider.GetRequiredService<MySqlServer>();
            await sqlserver.Start();
        }
    }
    class ClientSessionManagment
    {
        public void Add(ClientSession session)
        {

        }
    }
    class ProcessorFacotry
    {

        public ProcessorFacotry(IServiceProvider serviceProvider, ILogger<ProcessorFacotry> logger)
        {
            this.serviceProvider = serviceProvider;
            this.logger = logger;
        }
        private readonly IServiceProvider serviceProvider;
        private readonly ILogger logger;

        public ClientSession Session { get; internal set; }
        public Processor Processor { get; private set; }

        public bool CanNext => Processor != null && Processor.CanNext;
        public async Task Process()
        {

            if (Session.Sequence == 0)
            {
                Processor = serviceProvider.GetRequiredService<HandshakeProcessor>();

            }
            else if (Session.Sequence == 1)
            {
                Processor = serviceProvider.GetRequiredService<AuthProcessor>();
            }
            else
            {
                Processor = serviceProvider.GetRequiredService<QueryProcessor>();
            }
            try
            {
                await Processor.Process();


                Session.Sequence++;

            }
            catch (Exception ex)
            {
                logger.LogError(ex, "处理失败");
                Processor = null;
                throw;
            }

        }
    }
    public class MySqlServer
    {

        public MySqlServer(IServiceProvider serviceProvider, IOptions<MysqlOption> option, ILogger<MySqlServer> logger)
        {

            Option = option.Value;
            ServiceProvider = serviceProvider;
            this.logger = logger;
        }

        private readonly ILogger logger;

        public MysqlOption Option { get; }
        internal IServiceProvider ServiceProvider { get; set; }

        public async Task Start()
        {

            var listener = new TcpListener(IPAddress.Any, Option.Port);
            listener.Start();
            logger.LogInformation($"MySQL Mock Server running on port {Option.Port}");

            while (true)
            {
                var client = await listener.AcceptTcpClientAsync();
                _ = HandleClientAsync(client);
            }
        }



        private async Task HandleClientAsync(TcpClient client)
        {
            using var scope = ServiceProvider.CreateScope();
            try
            {
                var session = new ClientSession(client) { PasswordPlugin = Option.PasswordPlugin };
                var managment = ServiceProvider.GetRequiredService<ClientSessionManagment>();
                managment.Add(session);
                var facotry = scope.ServiceProvider.GetRequiredService<ProcessorFacotry>();
                facotry.Session = session;
                do
                {
                    await facotry.Process();

                } while (facotry.CanNext);


            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"HandleClientAsync");
            }

        }

    }
    static class BufferExtensions
    {
        public static byte[] CopyTo(byte[] source, int offset, int length)
        {

            byte[] date = new byte[length];

            Buffer.BlockCopy(source, offset, date, 0, length);
            return date;
        }
        public static byte[] Concat(byte[] left, byte[] right)
        {
            var tmp = new byte[left.Length + right.Length];
            Buffer.BlockCopy(left, 0, tmp, 0, left.Length);
            Buffer.BlockCopy(right, 0, tmp, left.Length, right.Length);
            return tmp; 
        }
        public static byte[] Concat(byte[] left, byte right)
        {
            var tmp = new byte[left.Length + 1];
            Buffer.BlockCopy(left, 0, tmp, 0, left.Length);
            tmp[left.Length] = right;
            return tmp; 
        }
    }
    class AuthProcessor : Processor
    {

        public AuthProcessor(ClientSession session, IUserManagement userManagement, ILogger<AuthProcessor> logger) : base(session, logger)
        {
            this.userManagement = userManagement;

        }
        private readonly IUserManagement userManagement;


        // 解析认证包中的数据库名
        public override async Task Process()
        {
            // 阶段2: 读取客户端认证包（序列号1）
            byte[] data = await ReadPacket();
            if (data.Length == 0) return;
            // 1. 读取客户端能力标志（4字节）
            uint clientCapabilities = (uint)(data[Offset] | (data[Offset + 1] << 8) | (data[Offset + 2] << 16) | (data[Offset + 3] << 24));
            Offset += 4;

            // 2. 读取最大包大小（4字节）
            uint maxPacketSize = BitConverter.ToUInt32(data, Offset);
            Offset += 4;

            // 3. 读取字符编码（1字节）
            byte charset = data[Offset];
            Offset += 1;

            // 4. 跳过保留字段（23字节）
            Offset += 23; // 关键修正点：必须跳过23字节！

            // 5. 读取用户名（以0x00结尾）
            Session.Username = ReadNullTerminatedString(data);
            var userprofile = userManagement.GetUser(Session.Username);
            var msg = $"Access denied for user '{Session.Username}' (using password: YES)";
            if (userprofile == null)
            {

                await SendErrorResponse(1045, msg, "user not find");
                return;
            }
        

            if (!ClientCapabilities.HasAuth(clientCapabilities))
            {
                msg = $"client capabilities  Auth required";

                await SendErrorResponse(1045, msg);
                return;
            }

            // 密码结构: [1字节长度] + [N字节加密数据]
            byte authResponseLength = data[Offset++];
            Session.AuthResponse = BufferExtensions.CopyTo(data, Offset, authResponseLength);
            Offset += authResponseLength;
            // 调试日志（关键调试信息）
            LogDebug($"Salt: {BitConverter.ToString(Session.AuthPluginData)} Length: {Session.AuthPluginData.Length}");
            LogDebug($"Response: {BitConverter.ToString(Session.AuthResponse)} Length: {Session.AuthResponse.Length}");

            if (authResponseLength != 20) // SHA1要求固定20字节
            {
                await SendErrorResponse(1045, "Invalid auth response length");
                return;
            }
            string actualPassword = userprofile.Password ?? "";
            if (string.IsNullOrEmpty(actualPassword))
            {
                msg = $"Access denied for user '{Session.Username}' (using password: NO)";

                await SendErrorResponse(1045, msg);
                return;
            }
            bool isValid = Session.PasswordPlugin switch
            {
                PasswordPlugin.mysql_native_password =>
                    PasswordValidator.ValidateSHA1(Session.AuthResponse, actualPassword, Session.AuthPluginData),
                PasswordPlugin.caching_sha2_password =>
                    PasswordValidator.ValidateSHA256(Session.AuthResponse, actualPassword, Session.AuthPluginData),
                _ => false
            };

            if (!isValid)
            {
                msg = $"Access denied for user '{Session.Username}' (using password: YES)";

                await SendErrorResponse(1045, msg);
                return;
            }


            // 仅在客户端指定数据库时读取
            if (ClientCapabilities.WithDB(clientCapabilities))
            {
                Session.Database = ReadNullTerminatedString(data);

                if (!userManagement.AssessRigth(Session.Username, Session.Database))
                {
                    msg = $"Unknown database '{Session.Database}'";

                    await SendErrorResponse(1045, msg);
                    return;
                }
            }

            await SendOkResponse();
            CanNext = true;


        }


    }
    class HandshakeProcessor : Processor
    {

        public HandshakeProcessor(ClientSession session, ILogger<HandshakeProcessor> logger) : base(session, logger)
        {
        }

        public override async Task<bool> Process()
        {
            // 阶段1: 发送握手包（序列号0）
            var handshake = BuildHandshakePacket();
            await Stream.WriteAsync(handshake, 0, handshake.Length);

            return true;
        }


        byte[] GenerateSalt(int length)
        {
            // 改用加密安全的随机数生成
            byte[] salt = new byte[length];
            using var rng = RandomNumberGenerator.Create();

            rng.GetBytes(salt);

            return salt;
        }

        // 构建符合 MySQL 5.6 的握手包
        // 构建握手包（序列号0）
        private byte[] BuildHandshakePacket()
        {
            // 能力标志（关键修改点）
            ushort lowerFlags = ClientCapabilities.GetLowerFlags();   // 低16位：包含 CLIENT_PROTOCOL_41 和 CLIENT_SECURE_CONNECTION
            ushort upperFlags = ClientCapabilities.GetUpperFlags();      // 高16位：添加 CLIENT_PLUGIN_AUTH
            // 生成盐的两个部分（8字节 + 12字节 = 20字节）
            byte[] saltPart1 = GenerateSalt(8);
            byte[] saltPart2 = GenerateSalt(12);
            byte[] saltPart2Modified = BufferExtensions.Concat(saltPart2, 0x00);
            string passwordPlugin = GetPasswordPluginName();
            Random random = new Random((int)DateTime.Now.Ticks);
            var connectioID = (uint)random.Next();
            using var writer = new PacketWriter();
            writer.WriteByte(0x0A);                     // 协议版本
            writer.WriteNullTerminated("5.6.0");    // 服务器版本
            writer.WriteUInt32(connectioID);                      // 连接 ID
            writer.WriteBytes(saltPart1);               // 盐第一部分（8字节）
            writer.WriteByte(0x00);                     // 保留填充
            writer.WriteUInt16(lowerFlags);             // 能力标志低位
            writer.WriteByte(0x21);                     // 字符集（UTF8）
            writer.WriteUInt16(ServerStatus.Autocommit);                 // 状态标志
            writer.WriteUInt16(upperFlags);             // 能力标志高位
            writer.WriteByte(0x14);                     // 盐总长度（20字节）
            writer.WriteBytes(new byte[10]);            // 保留字段
            writer.WriteBytes(saltPart2Modified);               // 盐第二部分（12字节）
            writer.WriteNullTerminated(passwordPlugin); // 认证插件名

            // 合并盐并存储在会话中
            Session.AuthPluginData = BufferExtensions.Concat(saltPart1, saltPart2);

            byte[] packet = writer.ToPacket(0);
            CanNext = true;
            return packet;
        }

        private string GetPasswordPluginName()
        {
            string passwordPlugin;
            switch (Session.PasswordPlugin)
            {
                case PasswordPlugin.mysql_native_password:
                    passwordPlugin = "mysql_native_password";
                    break;
                case PasswordPlugin.caching_sha2_password:
                    passwordPlugin = "caching_sha2_password";
                    break;
                default:
                    passwordPlugin = "mysql_native_password";
                    break;
            }

            return passwordPlugin;
        }
    }
    abstract class Processor
    {

        public Processor(ClientSession session, ILogger logger)
        {
            _stream = session.GetStream();
            _session = session;
            this.logger = logger;
        }
        private readonly Stream _stream;
        private readonly ClientSession _session;
        private readonly ILogger logger;

        public virtual bool CanNext { get; protected set; }
        protected byte CurrentSequence { get => _session.Sequence; set => _session.Sequence = value; }

        protected Stream Stream => _stream;

        protected ClientSession Session => _session;

        public int Offset { get; protected set; }

        public abstract Task Process();
        /// <summary>
        /// 获取文本
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public string ReadNullTerminatedString(byte[] data)
        {

            if (Offset >= data.Length) return string.Empty; // 防止越界
            int start = Offset;
            while (Offset < data.Length && data[Offset] != 0x00)
            {
                Offset++;
            }
            string value = Encoding.UTF8.GetString(data, start, Offset - start);
            Offset++; // 跳过Null终止符
            return value;
        }
        /// <summary>
        /// 读取包信息
        /// </summary>
        /// <returns></returns>
        public async Task<byte[]> ReadPacket()
        {
            byte[] header = new byte[4];
            int bytesRead = 0;

            while (bytesRead < 4)
            {
                int read = await Stream.ReadAsync(header, bytesRead, 4 - bytesRead);
                if (read == 0) return new byte[0];
                bytesRead += read;
            }

            int length = header[0] | (header[1] << 8) | (header[2] << 16);
          //  byte sequence = header[3];

            byte[] payload = new byte[length];
            bytesRead = 0;
            while (bytesRead < length)
            {
                int read = await Stream.ReadAsync(payload, bytesRead, length - bytesRead);
                if (read == 0) return new byte[0];
                bytesRead += read;
            }
            LogDebug($"Received:{CombineBytes(header, payload)}");
            return payload;
        }

        private string CombineBytes(params byte[][] array)
        {
            byte[] buffer = array.FirstOrDefault();
            for (int i = 1; i < array.Length; i++)
            {
                buffer = BufferExtensions.Concat(buffer, array[i]);
            }
            return BitConverter.ToString(buffer);
        }


        /// <summary>
        /// Eof包
        /// </summary>
        /// <returns></returns>
        public async Task SendEofPacket()
        {
            using var eofWriter = new PacketWriter();
            eofWriter.WriteByte(0xfe);
            eofWriter.WriteUInt16(ServerStatus.Autocommit); // 状态标志（必须包含）
            byte[] eofPacket = eofWriter.ToPacket(CurrentSequence++);

            LogDebug($"Send:{CombineBytes(eofPacket)}");
            await Stream.WriteAsync(eofPacket, 0, eofPacket.Length);
        }

        /// <summary>
        /// 发送错误响应并递增序列号
        /// </summary>
        /// <param name="errorCode"></param>
        /// <param name="errorMessage"></param>
        /// <param name="logMessage"></param>
        /// <returns></returns>
        public async Task SendErrorResponse(ushort errorCode, string errorMessage, string logMessage = null)
        {
            logger.LogWarning($"{logMessage}  code: {errorCode} message: {errorMessage}");
            using var writer = new PacketWriter();
            writer.WriteByte(0xFF); // 错误包标识
            writer.WriteUInt16(errorCode); // 错误码（例如 1045）
            writer.WriteByte((byte)'#'); // SQL状态标记
            writer.WriteBytes(Encoding.UTF8.GetBytes("HY000")); // SQL状态码（5字节）
            writer.WriteNullTerminated(errorMessage?.TrimEnd('\0') ?? string.Empty);
            byte[] errorPacket = writer.ToPacket(CurrentSequence);

            await Stream.WriteAsync(errorPacket, 0, errorPacket.Length);
            CurrentSequence++;
        }
        protected void LogDebug(string message)
        {
            logger.LogDebug(message);
        }
        /// <summary>
        /// 发送OK响应
        /// </summary>
        /// <returns></returns>
        public async Task SendOkResponse()
        {
            using var writer = new PacketWriter();
            writer.WriteByte(0x00); // OK标识
            writer.WriteUInt64(0); // Affected Rows
            writer.WriteUInt64(0); // Last Insert ID
            writer.WriteUInt16(ServerStatus.Autocommit); // 服务器状态
            byte[] okPacket = writer.ToPacket(CurrentSequence);
            await Stream.WriteAsync(okPacket, 0, okPacket.Length);
            CurrentSequence++;
        }



    }
    class QueryProcessor : Processor
    {

        public QueryProcessor(ClientSession session, ILogger<QueryProcessor> logger) : base(session, logger)
        {

        }

        /// <summary>
        /// 处理客户端查询请求
        /// </summary>
        /// <returns></returns>
        public override async Task Process()
        {
            var queryPacket = await ReadPacket();
            if (queryPacket.Length == 0)
            {
                return;
            }
            byte command = queryPacket[0];
            switch (command)
            {
                case 0x01: // COM_QUIT
                    return;
                case 0x0E: // COM_PING
                    {
                        await SendOkResponse();
                        CanNext = true; break;
                    }
                case 0x03: // COM_QUERY
                    {
                        string query = Encoding.UTF8.GetString(queryPacket, 1, queryPacket.Length - 1);
                        await HandleQuery(query);
                        CanNext = true;
                        break;
                    }
                default:
                    await SendErrorResponse(1047, "Unsupported command");
                    break;
            }

        }
        // 发送用户模拟数据
        private async Task SendMockUserData()
        {
            // 列定义
            using var columnWriter = new PacketWriter();
            columnWriter.WriteLengthEncodedInteger(2); // 列数
            columnWriter.WriteColumnDefinition("id", "INT");
            columnWriter.WriteColumnDefinition("name", "VARCHAR");
            byte[] columnPacket = columnWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(columnPacket, 0, columnPacket.Length);

            // 数据行
            using var rowWriter = new PacketWriter();
            rowWriter.WriteLengthEncodedInteger(1);
            rowWriter.WriteLengthEncodedString("Test User");
            byte[] rowPacket = rowWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(rowPacket, 0, rowPacket.Length);

            // EOF包
            await SendEofPacket();
        }
        private async Task SendDatabaseResponse()
        {
            // 列定义（1列）
            using var columnWriter = new PacketWriter();
            columnWriter.WriteLengthEncodedInteger(1); // 列数 = 1
            columnWriter.WriteColumnDefinition("DATABASE", "VARCHAR");
            byte[] columnPacket = columnWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(columnPacket, 0, columnPacket.Length);

            // 数据行（1个字段）
            using var rowWriter = new PacketWriter();
            rowWriter.WriteLengthEncodedString(Session.Database ?? "NULL");
            byte[] rowPacket = rowWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(rowPacket, 0, rowPacket.Length);

            // EOF包
            await SendEofPacket();
        }
        private async Task HandleSystemVariablesQuery()
        {
            // 列定义包
            using var columnWriter = new PacketWriter();
            columnWriter.WriteLengthEncodedInteger((ulong)SystemVariables.Count * 2);

            // 生成列定义（变量名和值）
            foreach (var kv in SystemVariables)
            {
                columnWriter.WriteColumnDefinition(kv.Key, "VARCHAR");
                columnWriter.WriteColumnDefinition(kv.Key + "_value", "VARCHAR");
            }

            byte[] columnPacket = columnWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(columnPacket, 0, columnPacket.Length);

            // 数据行包
            using var rowWriter = new PacketWriter();
            foreach (var kv in SystemVariables)
            {
                rowWriter.WriteLengthEncodedString(kv.Key);
                rowWriter.WriteLengthEncodedString(kv.Value);
            }
            byte[] rowPacket = rowWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(rowPacket, 0, rowPacket.Length);

            // EOF包
            await SendEofPacket();
        }

        private static readonly Dictionary<string, string> SystemVariables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
        {
            ["auto_increment_increment"] = "1",
            ["character_set_client"] = "utf8mb4",
            ["character_set_connection"] = "utf8mb4",
            ["character_set_results"] = "utf8mb4",
            ["character_set_server"] = "utf8mb4",
            ["collation_server"] = "utf8mb4_general_ci",
            ["collation_connection"] = "utf8mb4_general_ci",
            ["init_connect"] = "",
            ["interactive_timeout"] = "28800",
            ["license"] = "MIT",
            ["lower_case_table_names"] = "0",
            ["max_allowed_packet"] = "67108864",
            ["net_write_timeout"] = "60",
            ["performance_schema"] = "1",
            ["query_cache_size"] = "1048576",
            ["query_cache_type"] = "1",
            ["sql_mode"] = "STRICT_TRANS_TABLES",
            ["system_time_zone"] = "UTC",
            ["time_zone"] = "SYSTEM",
            ["transaction_isolation"] = "REPEATABLE-READ",
            ["wait_timeout"] = "28800"
        };
        // 分发查询处理逻辑
        private async Task HandleQuery(string query)
        {
            if (query.Contains("SELECT DATABASE", StringComparison.OrdinalIgnoreCase) || query.Contains("show databases", StringComparison.OrdinalIgnoreCase))
            {
                await SendDatabaseResponse();
                return;
            }
            var tableMatch = Regex.Match(query, @"from\s+(\w+)");
            if (tableMatch.Success)
            {
                string tableName = tableMatch.Groups[1].Value;
                switch (tableName)
                {
                    case "mock_products":
                        await SendMockUserData();
                        break;
                    case "systemVariables":
                        await HandleSystemVariablesQuery();
                        break;
                    default:

                        break;
                }
                return;
            }
            if (query.Contains("@@version", StringComparison.CurrentCultureIgnoreCase))
            {
                await SendVersionResponse();
            }
            else
            {
                await SendOkResponse();
            }
        }

        // 发送版本信息响应
        private async Task SendVersionResponse()
        {
            // 列定义包（必须包含完整字段）
            using var columnWriter = new PacketWriter();

            // 列数量（1列）
            columnWriter.WriteLengthEncodedInteger(1);

            // 列定义数据（每个字段必须按协议顺序写入）
            columnWriter.WriteColumnDefinition("@@version", "VARCHAR");
            byte[] columnPacket = columnWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(columnPacket, 0, columnPacket.Length);

            // 数据行包
            using var rowWriter = new PacketWriter();
            rowWriter.WriteLengthEncodedString("5.6.0");
            byte[] rowPacket = rowWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(rowPacket, 0, rowPacket.Length);

            // EOF包（必须包含状态标志）
            using var eofWriter = new PacketWriter();
            eofWriter.WriteByte(0xfe); // EOF标记
            eofWriter.WriteUInt16(0x0002); // 状态标志
            byte[] eofPacket = eofWriter.ToPacket(CurrentSequence++);
            await Stream.WriteAsync(eofPacket, 0, eofPacket.Length);
        }
    }
}